

/**
 * @author Carlos
 * @version 1.0
 * @created 09-oct-2013 05:23:43 p.m.
 */
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using System;
using GameEngine.Scenes;
namespace GameEngine.animations
{
    public class DetailAnimation: ICloneable
    {
        #region Attributes
        public static readonly int AnimationDefaultFrameTime = 200;

        //Actor using the animation
        public Actor actor { get; set; }
        //Name for Debugging usage
        public string name { get; set; }
        //Controll of the frames
        public int currentFrame { get; set; }
        public int currentTimeEffect { get; set; }
        public int frameTimer { get; set; }
        public int freqFrame { get; set; }
        public int fromFrame { get; set; }
        public int untilFrame { get; set; }
        //Restart animation after finished
        public bool loopAnimation { get; set; }
        //Restart effect after finished
        public bool loopEffect { get; set; }
        //Animation mirrored
        public bool mirroredHor { get; set; }
        public bool mirroredVer { get; set; }
        //Animation used
        public Animation animation { get; set; }
        public PostProcessEffect postProcessEffect { get; set; }
        #endregion

        #region Constructors

        public DetailAnimation(Actor actor, string name, Animation animation, int freqFrame, int fromFrame, int untilFrame, bool mirroredHor, bool mirroredVer)
        {
            this.actor = actor;
            this.name = name;
            this.currentFrame = fromFrame;
            this.frameTimer = 0;
            this.freqFrame = freqFrame;
            this.animation = animation;
            if(animation.postProcessEffect != null)
                this.postProcessEffect = (PostProcessEffect)animation.postProcessEffect.Clone();
            this.fromFrame = fromFrame;
            this.untilFrame = untilFrame;
            this.mirroredHor = mirroredHor;
            this.mirroredVer = mirroredVer;
            this.loopAnimation = true;
            this.loopEffect = false;
        }
        public DetailAnimation(Actor actor, string name, Animation animation, int freqFrame, int fromFrame, int untilFrame):
            this(actor, name, animation, freqFrame, fromFrame, untilFrame,false,false)
        {
        
        }
        public DetailAnimation(Actor actor, string name, Animation animation, int freqFrame) :
            this(actor,name,animation,freqFrame,0,animation.totalFrames-1)
        {
            
        }
        public DetailAnimation(Actor actor, string name, Animation animation)
            : this(actor, name, animation, AnimationDefaultFrameTime)
        {

        }
        public DetailAnimation() { } //only for clone usage
        #endregion
        #region Functionality

        
        public virtual Rectangle getRect()
        {

            Rectangle returnRect = new Rectangle();
            int frameWidth, frameHeight;
            frameWidth = animation.texture.Width / animation.framesX;
            frameHeight = animation.texture.Height / animation.framesY;
            int columnNumber = currentFrame % animation.framesX;
            int rowNumber = currentFrame / animation.framesX;
            returnRect.X = columnNumber * frameWidth;
            returnRect.Y = rowNumber * frameHeight;
            returnRect.Width = frameWidth;
            returnRect.Height = frameHeight;
            return returnRect;
        }
        public virtual void update(int dTime)
        {
            frameTimer += dTime;
            if (postProcessEffect != null)
            {
                currentTimeEffect += dTime;
                if (currentTimeEffect > postProcessEffect.durationEffect) 
                {
                    if (loopEffect)
                        currentTimeEffect -= postProcessEffect.durationEffect;
                    else
                        currentTimeEffect = postProcessEffect.durationEffect;
                }
                postProcessEffect.effect.Parameters["timeraslow"].SetValue(currentTimeEffect);
            }
            if (frameTimer > freqFrame)
            {
                currentFrame++;
                frameTimer -= freqFrame;
                if (currentFrame > untilFrame)
                {
                    SubjectAnimation.getInstance().animFinished(this);
                    if (loopAnimation) currentFrame = fromFrame;
                    else currentFrame = untilFrame;
                }
            }
        }
        #endregion

        public override string ToString()
        {
            string ans = "";
            ans += "Animation: " + animation.ToString() + "\n";
            return ans;
        }

        #region ICloneable Members

        public virtual object Clone()
        {
            Type type = this.GetType();
            DetailAnimation newDetailAnimation = (DetailAnimation)Activator.CreateInstance(type);
            newDetailAnimation.actor = this.actor;
            newDetailAnimation.name = this.name;
            newDetailAnimation.currentFrame = this.currentFrame;
            newDetailAnimation.currentTimeEffect = this.currentTimeEffect;
            newDetailAnimation.frameTimer = this.frameTimer;
            newDetailAnimation.freqFrame = this.freqFrame;
            newDetailAnimation.animation = this.animation;
            if(this.postProcessEffect!=null)
                newDetailAnimation.postProcessEffect = (PostProcessEffect)this.postProcessEffect.Clone();
            newDetailAnimation.fromFrame = this.fromFrame;
            newDetailAnimation.untilFrame = this.untilFrame;
            newDetailAnimation.mirroredHor = this.mirroredHor;
            newDetailAnimation.mirroredVer = this.mirroredVer;
            newDetailAnimation.loopAnimation = true;
            newDetailAnimation.loopEffect = true;
            return newDetailAnimation;
        }

        #endregion
    }
}